/****************************************************************************
**  Tite Interactive Text Engine (TiTE)
**  Copyright (C) 2010  Eisoft Group
**
**  This file is part of TiTE.
**
**  TiTE is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  TiTE is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with TiTE.  If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/

/*!
 * \file log.hpp
 *
 * \date 01/10/2011
 */

#ifndef TITE_CORE_LOG_HPP
#define TITE_CORE_LOG_HPP

#include <tite/core/log/detail/Log_.hpp>
#include <tite/core/singleton/singleton.hpp>

/*!
 * \namespace tite
 *
 * \brief The TiTE namespace.
 */
namespace tite
{
    /*!
     * \namespace core
     *
     * \brief The TiTE core namespace.
     */
    namespace core
    {
        typedef Log_<char> log_t; /*!< The Log type. */
        typedef singleton<log_t, priority_levels::Low> Log; /*!< The Log singleton. */
    
        /*!
         * \brief Helper function that prepares the logging buffer for "Info" 
         *        messages. To be used prior to operator<<.
         * 
         * \return Modified Log object.
         */
        inline log_t& log_I(void)
        {
            Log::GetInstance()->_prepare(log_levels::Info);
            return Log::GetInstanceRef();
        }

        /*!
         * \brief Helper function that prepares the logging buffer for "Debug" 
         *        messages. To be used prior to operator<<.
         * 
         * \return Modified Log object.
         */
    #if defined(DEBUG) || defined(_DEBUG)
        inline log_t& log_D(void)
        {
            Log::GetInstance()->_prepare(log_levels::Debug);
            return Log::GetInstanceRef();
        }
    #else
        class log_D
        {
        public:
            template<typename T>
            log_D& operator<<(const T & t) { return *this; }
        };
    #endif
    
        /*!
         * \brief Helper function that prepares the logging buffer for "Warning" 
         *        messages. To be used prior to operator<<.
         * 
         * \return Modified Log object.
         */
        inline log_t& log_W(void)
        {
            Log::GetInstance()->_prepare(log_levels::Warning);
            return Log::GetInstanceRef();
        }
    
        /*!
         * \brief Helper function that prepares the logging buffer for "Critical" 
         *        messages. To be used prior to operator<<.
         * 
         * \return Modified Log object.
         */
        inline log_t& log_C(void)
        {
            Log::GetInstance()->_prepare(log_levels::Critical);
            return Log::GetInstanceRef();
        }
    
        /*!
         * \brief Helper function that prepares the logging buffer for "Fatal" 
         *        messages. To be used prior to operator<<.
         * 
         * \return Modified Log object.
         */
        inline log_t& log_F(void)
        {
            Log::GetInstance()->_prepare(log_levels::Fatal);
            return Log::GetInstanceRef();
        }

        inline void log_add_listener(log_t::listener_const_ptr_t pLogListener)
        {
            Log::GetInstance()->addListener(pLogListener);
        }

        inline void log_add_listener(const listener_fn_t & listener)
        {
            class ___ListenerImpl : public log_t::listener_t
            {
            public:
                ___ListenerImpl(const listener_fn_t & l)
                    : m_func(l)
                {
                }

                virtual ~___ListenerImpl(void) {}

                virtual listener_fn_return_t logMessage(listener_fn_arg_msg_t message, listener_fn_arg_log_level_t messageLevel)
                {
                    m_func(message, messageLevel);
                }

            private:
                listener_fn_t m_func;
            };

            Log::GetInstance()->addListener(new ___ListenerImpl(listener));
        }
    }// End of core namespace
}// End of tite namespace

#endif /* TITE_CORE_LOG_HPP */